package edu.gzhu.guli.back.service.admin;

import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.stream.Collectors;

import org.modelmapper.ModelMapper;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import edu.gzhu.guli.core.common.ApplicationResult;
import edu.gzhu.guli.core.entity.Admin;
import edu.gzhu.guli.core.entity.Admin_;
import edu.gzhu.guli.core.entity.Role;
import edu.gzhu.guli.core.repository.AdminRepository;
import edu.gzhu.guli.core.repository.RoleRepository;
import lombok.AllArgsConstructor;

@Service
@AllArgsConstructor
public class AdminService {
  final AdminRepository adminRepository;
  final RoleRepository roleRepository;
  final PasswordEncoder encoder;
  final ModelMapper modelMapper;

  public ApplicationResult<List<AdminReadDto>> loadAllAdmin() {
    List<AdminReadDto> data = adminRepository.findAll()
        .stream()
        .map(it -> modelMapper.map(it, AdminReadDto.class))
        .collect(Collectors.toList());
    return ApplicationResult.succese(data);
  }

  public ApplicationResult<AdminReadDto> create(AdminCreateOrEditDto dto) {
    Optional<Admin> check = adminRepository.findByUsername(dto.getUsername());
    if (check.isPresent())
      return ApplicationResult.failure("用户名：" + dto.getUsername() + "已存在");
    Admin admin = modelMapper.map(dto, Admin.class);
    admin.setPassword(encoder.encode(dto.getPassword()));
    admin.setRole(loadDefaultRole());
    admin = adminRepository.save(admin);
    AdminReadDto data = modelMapper.map(admin, AdminReadDto.class);
    return ApplicationResult.succese(data);
  }

  public ApplicationResult<AdminReadDto> edit(Long adminId, AdminCreateOrEditDto dto) {
    Optional<Admin> check = adminRepository.findById(adminId);
    if (!check.isPresent())
      return ApplicationResult.failure("未找到ID为：" + adminId + "的用户");
    Admin admin = check.get();
    check = adminRepository.findOne(
        builder -> builder.andNotEquals(Admin_.ID, adminId)
            .andEquals(Admin_.USERNAME, dto.getUsername()).build());
    if (!check.isPresent())
      return ApplicationResult.failure("用户名为：" + dto.getUsername() + "的用户已存在");

    modelMapper.map(dto, admin);
    admin.setPassword(encoder.encode(dto.getPassword()));
    AdminReadDto data = modelMapper.map(admin, AdminReadDto.class);
    return ApplicationResult.succese(data);
  }

  public ApplicationResult<Object> delete(Long adminId) {
    adminRepository.deleteById(adminId);
    return ApplicationResult.succese();
  }

  // 为用户绑定角色
  public ApplicationResult<Object> assignRole(Long adminId, Long roleId) {
    Optional<Admin> checkAdmin = adminRepository.findById(adminId);
    if (!checkAdmin.isPresent())
      return ApplicationResult.failure("未找到目标用户");
    Optional<Role> checkRole = roleRepository.findById(roleId);
    if (!checkRole.isPresent())
      return ApplicationResult.failure("未找到目标角色");
    Admin admin = checkAdmin.get();
    Role role = checkRole.get();
    admin.setRole(role);
    adminRepository.save(admin);
    return ApplicationResult.succese();
  }

  private Role loadDefaultRole() {
    Optional<Role> check = roleRepository.findByName("ADMIN");
    return check.orElseThrow(NoSuchElementException::new);
  }
}
